package com.lyn.module_custom_camera;

import android.content.Context;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import androidx.annotation.NonNull;

import java.util.List;

/**
 * created by lyn at 2021/10/14
 */
public class LynCamera extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {
    private static final String TAG = "LynCamera";
    private SurfaceHolder holder;
    private Camera camera;
    private int cameraId;
    private Size size;
    private int displayOrientation;
    private CameraViewCallBack cameraViewCallBack;

    public LynCamera(Context context) {
        super(context);
    }

    public LynCamera(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    public void initialize(int cameraId, Size size) {
        this.cameraId = cameraId;
        this.size = size;
        holder = getHolder();
        holder.addCallback(this);
        this.setFocusable(true);
        this.setFocusableInTouchMode(true);
    }

    public void setDisplayOrientation(int displayOrientation) {
        this.displayOrientation = displayOrientation;
    }

    public void setCameraViewCallBack(CameraViewCallBack cameraViewCallBack) {
        this.cameraViewCallBack = cameraViewCallBack;
    }

    public Camera getCamera() {
        return camera;
    }

    public int getCameraId() {
        return cameraId;
    }

    public Size getSize() {
        return size;
    }

    public int getDisplayOrientation() {
        return displayOrientation;
    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                boolean openCamera = openCamera();
                if (openCamera) return;
                for (int i = 0; i < 3; i++) {
                    closeCamera();
                    openCamera = openCamera();
                    if (openCamera) break;
                }
            }
        }).start();

    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                closeCamera();
            }
        }).start();

    }

    /**
     * 打开摄像头
     *
     * @return
     */
    public boolean openCamera() {
        try {
            camera = Camera.open(cameraId);
            Camera.Parameters parameters = camera.getParameters();
            Size previewSize = size;
            parameters.setPreviewSize(previewSize.getWidth(), previewSize.getHeight());
            camera.setParameters(parameters);
            List<Camera.Size> previewSizes =
                    parameters.getSupportedPreviewSizes();
            for (Camera.Size size : previewSizes) {
                Log.i(TAG, "width:" + size.width + "height:" + size.height);
            }
            camera.setPreviewDisplay(holder);
            Camera.Size size = parameters.getPreviewSize();
            camera.addCallbackBuffer(new byte[size.width * size.height * 3 / 2]);
            camera.setPreviewCallbackWithBuffer(this);
            camera.setDisplayOrientation(displayOrientation);
            camera.startPreview();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 关闭摄像头
     *
     * @return
     */
    public boolean closeCamera() {
        try {
            if (camera != null) {
                camera.stopPreview();
                camera.release();
                camera = null;
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 开始摄像头预览
     *
     * @return
     */
    public boolean startPreview() {
        try {
            if (camera != null) {
                camera.startPreview();
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 暂停摄像头预览
     *
     * @return
     */
    public boolean stopPreview() {
        try {
            if (camera != null) {
                camera.stopPreview();
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    public void focusing() {
        if (camera == null) return;
        camera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {

            }
        });
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        camera.addCallbackBuffer(data);
        if (cameraViewCallBack == null) return;
        cameraViewCallBack.onCallback(data, size);
    }


    public interface CameraViewCallBack {
        void onCallback(byte[] data, Size size);
    }
}
